using System;
using System.Diagnostics.CodeAnalysis;
using System.Threading;
using System.Windows.Graphics;
using Microsoft.Xna.Framework.Graphics;

namespace Microsoft.Xna.Framework
{
	public class DrawableGameComponent : GameComponent, IDrawable
	{
		private bool visible = true;
		private bool initialized;
		private int drawOrder;
		private EventHandler<EventArgs> _visibleChanged;
		private EventHandler<EventArgs> _drawOrderChanged;

		public bool Visible
		{
			get
			{
				return visible;
			}
			set
			{
				if (visible == value)
					return;
				visible = value;
				OnVisibleChanged(this, EventArgs.Empty);
			}
		}

		public int DrawOrder
		{
			get
			{
				return drawOrder;
			}
			set
			{
				if (drawOrder == value)
					return;
				drawOrder = value;
				OnDrawOrderChanged(this, EventArgs.Empty);
			}
		}

		public GraphicsDevice GraphicsDevice
		{
			get { return GraphicsDeviceManager.Current.GraphicsDevice; }
		}

		public event EventHandler<EventArgs> VisibleChanged
		{
			add
			{
				EventHandler<EventArgs> eventHandler = _visibleChanged;
				EventHandler<EventArgs> comparand;
				do
				{
					comparand = eventHandler;
					eventHandler = Interlocked.CompareExchange(ref _visibleChanged, comparand + value, comparand);
				}
				while (eventHandler != comparand);
			}
			remove
			{
				EventHandler<EventArgs> eventHandler = _visibleChanged;
				EventHandler<EventArgs> comparand;
				do
				{
					comparand = eventHandler;
					eventHandler = Interlocked.CompareExchange(ref _visibleChanged, comparand - value, comparand);
				}
				while (eventHandler != comparand);
			}
		}

		public event EventHandler<EventArgs> DrawOrderChanged
		{
			add
			{
				EventHandler<EventArgs> eventHandler = _drawOrderChanged;
				EventHandler<EventArgs> comparand;
				do
				{
					comparand = eventHandler;
					eventHandler = Interlocked.CompareExchange(ref _drawOrderChanged, comparand + value, comparand);
				}
				while (eventHandler != comparand);
			}
			remove
			{
				EventHandler<EventArgs> eventHandler = _drawOrderChanged;
				EventHandler<EventArgs> comparand;
				do
				{
					comparand = eventHandler;
					eventHandler = Interlocked.CompareExchange(ref _drawOrderChanged, comparand - value, comparand);
				}
				while (eventHandler != comparand);
			}
		}

		public DrawableGameComponent(Game game)
			: base(game)
		{
		}

		public override void Initialize()
		{
			base.Initialize();

			if (!initialized)
				LoadContent();

			initialized = true;
		}

		protected override void Dispose(bool disposing)
		{
			if (disposing)
				UnloadContent();

			base.Dispose(disposing);
		}

		public virtual void Draw(GameTime gameTime)
		{
		}

		protected virtual void LoadContent()
		{
		}

		protected virtual void UnloadContent()
		{
		}

		[SuppressMessage("Microsoft.Security", "CA2109:ReviewVisibleEventHandlers")]
		protected virtual void OnDrawOrderChanged(object sender, EventArgs args)
		{
			if (_drawOrderChanged == null)
				return;
			_drawOrderChanged((object)this, args);
		}

		[SuppressMessage("Microsoft.Security", "CA2109:ReviewVisibleEventHandlers")]
		protected virtual void OnVisibleChanged(object sender, EventArgs args)
		{
			if (_visibleChanged == null)
				return;
			_visibleChanged((object)this, args);
		}
	}
}